
#pragma once

enum DbgLineType
{
    dl_Empty,
    dl_Comment, 
    dl_Function,
    dl_LocalFunction,
    dl_Variable,
    dl_LocalVariable,
    dl_ObjectDeclaration,
    dl_AsmCode
};

class CDebugLine : public xobject
{
public:
    CDebugLine(){
        m_lineType = dl_Empty;
        m_dwIndex  = 0;
        m_bHasBreakpoint = FALSE;
        m_pFunciton = NULL;
    }

    CDebugLine( DbgLineType _lt, DWORD dwIdx, LPCSTR lpszName, symbolref pSym ) {
        m_lineType = _lt;
        m_dwIndex  = dwIdx;
        m_csName   = lpszName;
        m_bHasBreakpoint = FALSE;
        m_pFunciton = pSym;
    }

    CDebugLine( const CDebugLine& dl ) { 
        m_lineType = dl.m_lineType;
        m_dwIndex  = dl.m_dwIndex;
        m_bHasBreakpoint = dl.m_bHasBreakpoint;
        m_pFunciton = dl.m_pFunciton;
    }

    virtual ~CDebugLine(){}

    IMPLEMENT_SYSTEM_XUNKNOWN()

        CDebugLine& operator=( const CDebugLine& dl ) {
            if( this == &dl )
                return *this;
            m_lineType = dl.m_lineType;
            m_dwIndex  = dl.m_dwIndex;
            m_bHasBreakpoint = dl.m_bHasBreakpoint;
            m_pFunciton = dl.m_pFunciton;
            return *this;
    }

    inline DbgLineType GetLineType() const { return m_lineType; }
    inline DWORD       GetSymbolIndex() const { return m_dwIndex; }
    inline const string& GetName() const { return m_csName; }
    inline symbolref   GetFunction() const { return m_pFunciton; } 

    inline void        SetBreakpoint( BOOL bTure ) { if( m_lineType == dl_AsmCode ) m_bHasBreakpoint = bTure; }
    inline BOOL        HasBreakpoint() const { return m_bHasBreakpoint; }

private:
    DbgLineType m_lineType;
    DWORD       m_dwIndex; // can be index to data or function or IP in the code - it depends on type.
    string      m_csName;  // name of the type (can be object)
    symbolref   m_pFunciton; // function symbol associated with the line of code
    BOOL        m_bHasBreakpoint;
   
};

typedef CDebugLine* DbgLineRef;
typedef xarray<DbgLineRef, CCopyObject<DbgLineRef>, CDeleteObject<DbgLineRef> >  DBGLINES_ARRAY;

//////////////////////////////////////////////////////////////////////////
//
class CDisassemblerRTF
{
public:
    CDisassemblerRTF( XRuntime *pRT );
    virtual ~CDisassemblerRTF();

    void Disassemble( CString& csAsmRTFOut, DBGLINES_ARRAY& dbgLinesOut );

private:
    void DisassembleVariable( SymbolRef typeName, symbolref pSym, BOOL bLocal );
    void DisassembleFunction( SymbolRef typeName, symbolref pSym, BOOL bLocal );
    void DisassembleClass( symbolref pCls );
    void DisassembleCode( symbolref pSym );

    void AppendString( const CString& str, DbgLineType lnType, DWORD dwIdx, string *pcsName, symbolref pFunc = NULL );
    void AppendString( const CString& str ) { m_csAsmRTF += str; }

    XRuntime        *m_pRT;
    CString          m_csAsmRTF;
    DBGLINES_ARRAY  *m_pLineArray;
};